//
//  XQWCDBVC.swift
//  XQSqliteDemo
//
//  Created by WXQ on 2021/3/9.
//

import UIKit
import SnapKit
import XQAlert
import MJRefresh
import XQProjectTool
import WCDBSwift
import XQWCDB

/// 测试机子是 iPhone 7
class XQWCDBVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    private let cellReuseIdentifier = "cell"
    private let headerReuseIdentifier = "headerReuseIdentifier"
    private let tableView = UITableView.init(frame: .zero, style: .plain)
    private var dataArr = [HomeModel]()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "WCDB"
        
        self.navigationItem.rightBarButtonItems = [
            .init(title: "添加", style: .plain, target: self, action: #selector(respondsToAdd)),
            .init(title: "测试", style: .plain, target: self, action: #selector(respondsToTest))
        ]
        
        XQWCDB.shared.initDB()
        HomeModel.xq_createTable()
        PeopleModel.xq_createTable()
        
        self.initTableView()
        
        self.tableView.mj_header = MJRefreshNormalHeader.init(refreshingBlock: { [unowned self] in
            self.getData()
        })
        self.tableView.mj_header?.beginRefreshing()
        
    }
    
    private func initTableView() {
        self.view.addSubview(self.tableView)
        self.tableView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        self.tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: self.cellReuseIdentifier)
        
        self.tableView.register(ViewControllerHeaderView.classForCoder(), forHeaderFooterViewReuseIdentifier: self.headerReuseIdentifier)
        self.tableView.sectionHeaderHeight = 110
        
        self.tableView.delegate = self
        self.tableView.dataSource = self
    }
    
    private func getData() {
        DispatchQueue.init(label: "test_getData").async {
            
            print(Date().timeIntervalSince1970)
            self.dataArr = HomeModel.xq_getObjects()
            print(Date().timeIntervalSince1970)
            
//            let models: [HomeModel]? = try? XQWCDB.shared.database?.getObjects(fromTable: HomeModel.xq_table, where: nil, orderBy: nil, limit: 3, offset: 1)
//            self.dataArr = models ?? []
            
            // 当数量多的时候，这样循环查，性能会比较差
            // 比如 HomeModel 到达10万条，就需要8 ~ 10秒左右, 而且还是在没有什么 PeopleModel 下
//            for item in self.dataArr {
//                item.peopleArr = PeopleModel.xq_getObjects(with: PeopleModel.CodingKeys.homeId.is(item.homeId))
//            }
            
//            self.dataArr.removeAll()
//            let multiSelect = try? XQWCDB.shared.database?.prepareMultiSelect(on: HomeModel.CodingKeys.homeId.in(table: HomeModel.xq_table), PeopleModel.CodingKeys.homeId.in(table: PeopleModel.xq_table), fromTables: [HomeModel.xq_table, PeopleModel.xq_table])
//
//            while let object = try? multiSelect?.nextMultiObject() {
//
//                if let hModel = object[HomeModel.xq_table] as? HomeModel {
//                    self.dataArr.append(hModel)
//                }
//
//            }
            
            DispatchQueue.main.async {
                self.tableView.reloadData()
                self.tableView.mj_header?.endRefreshing()
            }
            
        }
        
    }
    
    // MARK: - responds
    
    @objc private func respondsToAdd() {
        XQSystemAlert.alert(withTitle: "添加", message: nil, contentArr: ["确定"], cancelText: "取消", vc: self, textFieldCount: 1) { (_, tf) in
            tf.placeholder = "请输入名称"
        } contentCallback: { (alert, _) in
            
            let name = alert.textFields?.first?.text ?? ""
            
            let hModel = HomeModel()
            hModel.name = name
            
            hModel.jsonModel = HomeModel.OtherDataModel()
            hModel.jsonModel?.sizeStr = "100平方米"
            
            HomeModel.xq_insert(with: [hModel])
            self.getData()
            
        } cancelCallback: { (_) in
            
        }
        
    }
    
    @objc private func respondsToTest() {
        XQSystemAlert.actionSheet(withTitle: nil, message: nil, contentArr: ["删除全部", "循环删除", "事务循环删除", "循环插入", "事务循环插入", "获取有多少条数据"], cancelText: "取消", vc: self) { (_, index) in
            
            switch index {
            case 0:
                self.deleteAll()
            case 1:
                self.deleteAllLoop()
            case 2:
                self.deleteAllTransaction()
                
            case 3:
                self.inserLoop()
                
            case 4:
                self.inserTransaction()
                
            case 5:
                self.getHomeCount()
                
            default:
                break
            }
            
        } cancelCallback: { (_) in
            
        }
        
    }
    
    private func getHomeCount() {
        // 1百万条数据，1.5 秒左右
        print(Date().timeIntervalSince1970)
        print(HomeModel.xq_getCount())
        print(Date().timeIntervalSince1970)
    }
    
    private func inserLoop() {
        // 1万条，0.1 秒左右就可以了
        // 100万条，14 秒左右
        print(Date().timeIntervalSince1970)
        
        var arr = [HomeModel]()
        for item in 0..<1000 {
            let hModel = HomeModel()
            hModel.name = "name\(item)"
            arr.append(hModel)
        }
        
        print(Date().timeIntervalSince1970)
        
        HomeModel.xq_insert(with: arr)
        
        print(Date().timeIntervalSince1970)
        
        self.getData()
    }
    
    private func inserTransaction() {
        // 1万条，0.1 秒左右就可以了
        // 100万条，11 秒左右
        print(Date().timeIntervalSince1970)
        
        var arr = [HomeModel]()
        for item in 0..<1000000 {
            let hModel = HomeModel()
            hModel.name = "name\(item)"
            arr.append(hModel)
        }
        print(Date().timeIntervalSince1970)
        
        try? XQWCDB.shared.database?.run(transaction: {
            HomeModel.xq_insert(with: arr)
        })
        
        print(Date().timeIntervalSince1970)
        
        self.getData()
    }
    
    private func deleteAllLoop() {
        DispatchQueue.init(label: "delete").async {
            // 循环删除, 1万条, 需要 14 秒
            // 不能像 sql 那样，直接提交所有语句上去吗？感觉那样会快很多
            print(Date().timeIntervalSince1970)
            for item in self.dataArr {
                HomeModel.xq_delete(with: HomeModel.CodingKeys.homeId.is(item.homeId))
            }
            print(Date().timeIntervalSince1970)
            
            PeopleModel.xq_delete()

            DispatchQueue.main.async {
                self.getData()
            }
        }
    }
    
    private func deleteAllTransaction() {
        DispatchQueue.init(label: "delete").async {
            // 事务删除, 1万条, 快一点，12 秒
            // 不能像 sql 那样，直接提交所有语句上去吗？感觉那样会快很多
            print(Date().timeIntervalSince1970)
            
            try? XQWCDB.shared.database?.run(transaction: {
                for item in self.dataArr {
                    HomeModel.xq_delete(with: HomeModel.CodingKeys.homeId.is(item.homeId))
                }
            })
            
//            let delete = try? XQWCDB.shared.database?.prepareDelete(fromTable: HomeModel.xq_table)
//            for item in self.dataArr {
//                delete?.where(HomeModel.CodingKeys.homeId.is(item.homeId))
//                try? delete?.execute()
//            }
            
            print(Date().timeIntervalSince1970)
            
            PeopleModel.xq_delete()

            DispatchQueue.main.async {
                self.getData()
            }
        }
    }
    
    private func deleteAll() {
        // 直接删除整个表，10万条也很快，基本一瞬间就删除完了
        HomeModel.xq_delete()
        PeopleModel.xq_delete()
        self.getData()
    }
    
    private func editHomeName(_ hModel: HomeModel) {
        XQSystemAlert.alert(withTitle: "修改", message: nil, contentArr: ["确定"], cancelText: "取消", vc: self, textFieldCount: 1) { (_, tf) in
            tf.placeholder = "请输入名称"
        } contentCallback: { (alert, _) in
            
            let name = alert.textFields?.first?.text ?? ""
            hModel.name = name
            HomeModel.xq_update(with: hModel, propertyConvertibleList: [HomeModel.CodingKeys.name], where: HomeModel.CodingKeys.homeId.is(hModel.homeId))
            self.getData()
            
        } cancelCallback: { (_) in
            
        }
    }
    
    private func addPeople(_ hModel: HomeModel) {
        XQSystemAlert.alert(withTitle: "添加", message: nil, contentArr: ["确定"], cancelText: "取消", vc: self, textFieldCount: 1) { (_, tf) in
            tf.placeholder = "请输入名称"
        } contentCallback: { (alert, _) in
            
            let name = alert.textFields?.first?.text ?? ""
            
            let model = PeopleModel()
            model.name = name
            model.homeId = hModel.homeId
            
            PeopleModel.xq_insert(with: [model])
            self.getData()
            
        } cancelCallback: { (_) in
            
        }
    }
    
    private func editPeopleName(_ pModel: PeopleModel) {
        XQSystemAlert.alert(withTitle: "修改", message: nil, contentArr: ["确定"], cancelText: "取消", vc: self, textFieldCount: 1) { (_, tf) in
            tf.placeholder = "请输入名称"
        } contentCallback: { (alert, _) in
            
            let name = alert.textFields?.first?.text ?? ""
            pModel.name = name
            
            PeopleModel.xq_update(with: pModel, propertyConvertibleList: [PeopleModel.CodingKeys.name], where: PeopleModel.CodingKeys.pId.is(pModel.pId))
            self.getData()
            
        } cancelCallback: { (_) in
            
        }
    }
    
    // MARK: - UITableViewDataSource
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.dataArr.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.dataArr[section].peopleArr.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: self.cellReuseIdentifier, for: indexPath)
        let model = self.dataArr[indexPath.section].peopleArr[indexPath.row]
        cell.textLabel?.text = model.name
        return cell
    }
    
    // MARK: - UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let model = self.dataArr[indexPath.section].peopleArr[indexPath.row]
        self.editPeopleName(model)
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: self.headerReuseIdentifier) as? ViewControllerHeaderView
        
        let model = self.dataArr[section]
        headerView?.titleLab.text = "\(model.name ?? "")\n创建日期: \(model.createDate)\n大小: \(model.jsonModel?.sizeStr ?? "") 价格: \(model.jsonModel?.price ?? 0)"
        
        headerView?.titleLab.isUserInteractionEnabled = true
        headerView?.titleLab.xq_addTap(callback: { [unowned self] (gesture) in
            self.editHomeName(model)
        })
        
        headerView?.addBtn.xq_addEvent(.touchUpInside, callback: { [unowned self] (sender) in
            self.addPeople(model)
        })
        
        headerView?.deleteBtn.xq_addEvent(.touchUpInside, callback: { [unowned self] (sender) in
            HomeModel.xq_delete(with: HomeModel.Properties.homeId.is(model.homeId))
            self.getData()
        })
        
        return headerView
    }
    
    deinit {
        print(#function, self.classForCoder)
    }

}
